package itsm.isperp.framework.message.impl;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.domain.UploadInfo;
import itsm.isperp.framework.service.UploadFileService;
import itsm.isperp.framework.utils.FileUploadUtils;
import itsm.isperp.framework.utils.HtmlUtil;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.module.entity.app.AppUser;
import itsm.isperp.module.entity.incident.IcdIncident;
import itsm.isperp.module.service.app.AppUserService;
import itsm.isperp.module.service.incident.IcdIncidentService;
import itsm.isperp.workflow.service.BpmProcessRunService;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import org.springframework.jdbc.core.JdbcTemplate;

import com.sun.mail.pop3.POP3Folder;

public class EmailReader {

  public static final String BEAN_ID = "isperp.emailReader";
  private Session session;
  private static String attachPath = "";

  private static boolean SESSION_REFRESH = false;
  //private static StringBuffer bodytext = new StringBuffer();//存放邮件内容

  public static void refreshCache() {
    SESSION_REFRESH = true;
  }

  public void read() throws Exception {
    this.readMail();
  }
  
  
   public static int daysBetween(Date date1,Date date2)  
      {  
          Calendar cal = Calendar.getInstance();  
          cal.setTime(date1);  
          long time1 = cal.getTimeInMillis();               
          cal.setTime(date2);  
          long time2 = cal.getTimeInMillis();       
          long between_days=(time2-time1)/(1000*3600*24);  
            
         return Integer.parseInt(String.valueOf(between_days));         
      }  

  /**
   * 发送邮件
   * 
   * @param message
   * @param files
   * @throws Exception
   */
  public void readMail() throws Exception {
    Session session = this.getMailSession();
    Folder folder = null;
    Store store = null;
    String imapserver = ContextHolder.getConfigByKey("readMailPop3Server"), user = ContextHolder
        .getConfigByKey("readMailUser"), pwd = ContextHolder
        .getConfigByKey("readMailPassword");

    BpmProcessRunService bpmProcessRunService = ContextHolder
        .getSpringBean("bpmProcessRunService");
    IcdIncidentService icdIncidentService = ContextHolder
        .getSpringBean("icdIncidentService");
    bpmProcessRunService = ContextHolder
        .getSpringBean("bpmProcessRunService");
    AppUserService appUserService = ContextHolder
        .getSpringBean("appUserService");
    // boolean delete = false;
    try {
      System.out.println("-----------------服务器Pop3Server：" + imapserver+ " 封--------------");
      store = session.getStore("pop3"); // 使用imap会话机制，连接服务器
      store.connect(imapserver, user, pwd);
      folder = store.getFolder("INBOX"); // 收件箱
      
      
      // 使用只读方式打开收件箱
            folder.open(Folder.READ_WRITE);
        
      if (folder instanceof POP3Folder) { 

          POP3Folder inbox = (POP3Folder) folder; 
          
          Message[] msgs = inbox.getMessages();
          System.out.println("-----------------您的邮箱共有邮件：" + msgs.length+ " 封--------------");
          for (Message msg : msgs) {
            //int emailNo=msg.getMessageNumber();
            Date sdt=msg.getSentDate();
            Date now=new Date();
            int diffDay=daysBetween(sdt,now);
            if(diffDay>2)
              continue;
            MimeMessage msg1 = (MimeMessage) msg;
            String mid =  inbox.getUID(msg1);
            InternetAddress ia = (InternetAddress) msg.getFrom()[0];
            String address = ia.getAddress();
            if(!checkIfExistsEmail(mid))
            {
              IcdIncident icd = new IcdIncident();
                StringBuffer bodytext = new StringBuffer();
              icd.setSource("邮件");
            //  icd.setMailId(mid);
              if(msg.getSubject()!=null)
              icd.setTitle(MimeUtility.decodeText(msg.getSubject()));
              
              String contentType = msg.getContentType();
              if (contentType.startsWith("text/plain")) {
                getMailContent(msg,bodytext, true);
              } else
                getMailContent(msg,bodytext, false);
              String descriptionHtml=bodytext.toString();
              String description=HtmlUtil.Html2Text(descriptionHtml);
              icd.setDescription(description);
              //icd.setDescriptionHtml(descriptionHtml);
              

              JqGridRequest req = new JqGridRequest();
              req.addFilterRule("email", JqGridFilterRuleOp.eq, address);
              req.isQueryOne(true);
              List<AppUser> us = appUserService.findAll(req);
              if (us != null && us.size() > 0) {
                icd.setCusUserId(us.get(0).getId());

              } else {
                icd.setCusUserId("000");
                icd.setTitle("未知用户[" + address + "]" + icd.getTitle());
              }
              icdIncidentService.saveOrUpdate(icd);

              String id = icd.getId();

              bpmProcessRunService.startProcess("admin", "incidentProcess",
                  id, "邮件报障");
              bodytext=null;
              if(isContainAttach(msg))
                  saveAttachMent(msg, id);
            }
            // 插件一条工单，并提交
            // Map<String, Object> vars = new HashMap<>();
            // vars.put("message", msg);
            // Binding bd = new Binding(vars);
            // GroovyShell shell = new GroovyShell(bd);
            // shell.evaluate(script);
            //msg.setFlag(Flag.DELETED, true);
          }
      }

      

    } catch (Exception ex) {
      System.err.println("不能以读写方式打开邮箱!");
      ex.printStackTrace();
    } finally {
      // 释放资源
      try {
        if (folder != null)
          folder.close(true); // 退出收件箱时,删除做了删除标识的邮件
        if (store != null)
          store.close();
        
      } catch (Exception bs) {
        bs.printStackTrace();
      }
      
    }

  }
  
  public boolean checkIfExistsEmail(String msgId)
  {
    String sql="select *  from icd_incident where mail_id='"+msgId+"' and source='邮件'";
    JdbcTemplate jdbcTemplate = ContextHolder
        .getSpringBean("jdbcTemplate");
    List<Map<String,Object>> list=jdbcTemplate.queryForList(sql);
    if(list.size()>0)
    {
      return true;
    }else
    {
      return false;
    }
    
  }
  
  public boolean checkIfAllowGetMail(String address)
  {
    boolean result=false;
    String configAllowAddress = ContextHolder
        .getConfigByKey("allowMails");
    String[] configAllowAddressList=configAllowAddress.split(",");
    for(String ad:configAllowAddressList)
    {
      if(ad.indexOf("*@")>-1)
      {
        String tempMailServerAddress=ad.split("@")[1];
        if(address.indexOf(tempMailServerAddress)>-1)
        {
          result=true;
        }
      }else
      {
         if(ad.equals(address))
         {
           result=true;
         }
        
      }
      
    }
    return result;
  }

  public static void getMailContent(Part part,StringBuffer bodytext,boolean flag) throws Exception {
    String contentType = part.getContentType();
    int nameindex = contentType.indexOf("name");
    boolean conname = false;
    if (nameindex != -1)
      conname = true;
    if (part.isMimeType("text/plain") && !conname && flag) {
      bodytext.append((String) part.getContent());
      flag = false;
    } else if (part.isMimeType("text/html") && !conname && flag == false) {
      bodytext.append((String) part.getContent());
    } else if (part.isMimeType("multipart/*")) {
      Multipart multipart = (Multipart) part.getContent();
      int counts = multipart.getCount();
      for (int i = 0; i < counts; i++) {
        getMailContent(multipart.getBodyPart(i),bodytext, flag);
      }
    }

    else if (part.isMimeType("message/rfc822")) {
      getMailContent((Part) part.getContent(),bodytext, flag);
    }

    else {
    }
  }
   
  // 保存附件
    public static void saveAttachMent(Part part,String id) throws Exception {
      String fileName = "";
      if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        for (int i = 0; i < mp.getCount(); i++) {
          BodyPart mpart = mp.getBodyPart(i);
          String disposition = mpart.getDisposition();
          if ((disposition != null)
              && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                  .equals(Part.INLINE)))) {
            fileName = MimeUtility.decodeText(mpart.getFileName());
            if (fileName.toLowerCase().indexOf("gb2312") != -1) {
              fileName = MimeUtility.decodeText(fileName);
            }
            saveFile(fileName, mpart.getInputStream(),id);
          } else if (mpart.isMimeType("multipart/*")) {
            saveAttachMent(mpart,id);
          } else {
            fileName = mpart.getFileName();
            if ((fileName != null)
                && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
              fileName = MimeUtility.decodeText(fileName);
              saveFile(fileName, mpart.getInputStream(),id);
            }
          }
        }
      } else if (part.isMimeType("message/rfc822")) {
        saveAttachMent((Part) part.getContent(),id);
      }
    }

    private static void saveFile(String fileName, InputStream in,String id)
        throws Exception {
      String storedir = "E:\\temp\\";
      File storefile = new File(storedir + File.separator + fileName);
      if (!storefile.getParentFile().exists()) // 如果文件不存在
        storefile.getParentFile().mkdirs(); // 创建新文件
      attachPath = storefile.getParentFile().getAbsolutePath(); // 附件路径指向文件路径
      System.out.println("storefile's path: " + storefile.toString());
      BufferedOutputStream bos = null;
      BufferedInputStream bis = null;
      try {
        bos = new BufferedOutputStream(new FileOutputStream(storefile));
        bis = new BufferedInputStream(in);
        int c;
        while ((c = bis.read()) != -1) {
          bos.write(c);
          bos.flush();
        }
      } catch (Exception exception) {
        exception.printStackTrace();
        throw new Exception("文件保存失败!");
      } finally {

        bos.close();
        bis.close();
      }
      String[] tempExt=fileName.split("\\.");
      UploadInfo uploadInfo = FileUploadUtils.persist(storefile, "."+tempExt[1],
          fileName);
      uploadInfo.setSourceId(id);
      uploadInfo.setMeno("youjiande");
      UploadFileService<UploadInfo> uploadFileService = ContextHolder
          .getSpringBean("appUploadFileService");

      uploadFileService.saveOrUpdate(uploadInfo);
    }

    /**
     * 是否包含附件
     * 
     * @param part
     * @return
     * @throws Exception
     */
    public static boolean isContainAttach(Part part) throws Exception {
      boolean attachflag = false;
      String contentType = part.getContentType();
      if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        for (int i = 0; i < mp.getCount(); i++) {
          BodyPart mpart = mp.getBodyPart(i);
          String disposition = mpart.getDisposition();
          if ((disposition != null)
              && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                  .equals(Part.INLINE))))
            attachflag = true;
          else if (mpart.isMimeType("multipart/*")) {
            attachflag = isContainAttach((Part) mpart);
          } else {
            String contype = mpart.getContentType();
            if (contype.toLowerCase().indexOf("application") != -1)
              attachflag = true;
            if (contype.toLowerCase().indexOf("name") != -1)
              attachflag = true;
          }
        }
      } else if (part.isMimeType("message/rfc822")) {
        attachflag = isContainAttach((Part) part.getContent());
      }
      return attachflag;
    }

  /**
   * 获取有效的缓存
   * 
   * @return
   */
  private Session getMailSession() {
    if (session == null || SESSION_REFRESH == true) {
      resetSession();
    }
    return session;
  }

  private void resetSession() {
    String pop3server = ContextHolder.getConfigByKey("readMailPop3Server");
    SESSION_REFRESH = false;
    Properties props = new Properties();
    props.setProperty("mail.store.protocol", "pop3"); // 协议
    props.setProperty("mail.pop3.port", "110"); // 端口
    props.setProperty("mail.pop3.host", pop3server); // pop3服务器

    session = Session.getDefaultInstance(props, null);

  }
}
